package com.googlecode.yoohoo.xmppcore.protocol.parsing;

import java.util.List;

import com.googlecode.yoohoo.xmppcore.protocol.XmlLangText;
import com.googlecode.yoohoo.xmppcore.protocol.XmppProtocolException;
import com.googlecode.yoohoo.xmppcore.protocol.stanza.Message;
import com.googlecode.yoohoo.xmppcore.protocol.stanza.error.BadRequest;

public class MessageParserFactory extends AbstractXmppParserFactory<Message> {
	private static final ProtocolKey PROTOCL_KEY_MESSAGE = new ProtocolKey("message", null);

	@Override
	public IXmppParser<Message> createParser() {
		return new MessageParser();
	}
	
	private class MessageParser extends StanzaParser<Message> {
		private static final String PATH_MESSAGE_SUBJECT = "message/subject";
		private static final String PATH_MESSAGE_BODY = "message/body";
		private static final String PATH_MESSAGE_THREAD = "message/thread";
		
		private XmlLangText subject;
		private XmlLangText body;
		
		@Override
		protected Message createStanza() {
			return new Message();
		}
		
		@Override
		protected void doProcessAttributes(String path, List<Attribute> attributes) {
			if (PATH_MESSAGE_SUBJECT.equals(path)) {
				subject = new XmlLangText();
				subject.setXmlLang(ParsingUtils.readXmlLang(attributes));
			} else if (PATH_MESSAGE_BODY.equals(path)) {
				body = new XmlLangText();
				body.setXmlLang(ParsingUtils.readXmlLang(attributes));
			} else if (PATH_MESSAGE_THREAD.equals(path)) {
				if (attributes.size() > 0)
					throw new XmppProtocolException(new BadRequest("Element 'thread' doesn't allows attribute."));
				
				if (stanza.getThread() != null) {
					throw new XmppProtocolException(new BadRequest("Reduplicated 'thread' element."));
				}
			} else {
				throw new XmppProtocolException(new BadRequest(String.format("Invalid element '%s'.", path)));
			}
		}
		
		@Override
		public void processText(String path, String text) {
			if (subject != null) {
				subject.setText(text);
				stanza.getSubjects().add(subject);
				subject = null;
			} else if (body != null) {
				body.setText(text);
				stanza.getBodies().add(body);
				body = null;
			} else if ("message/thread".equals(path)) {
				stanza.setThread(text);
			}
		}
	}

	@Override
	public ProtocolKey getProtocolKey() {
		return PROTOCL_KEY_MESSAGE;
	}

}
